package com.gcstorage.tvdev.util;

import android.text.TextUtils;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.blankj.utilcode.util.ZipUtils;

import com.gcstorage.tvdev.base.BaseApplication;
import com.gcstorage.tvdev.bean.H5AppInfo;
import com.gcstorage.tvdev.constants.AppConstant;
import com.gcstorage.tvdev.constants.GlobalConstants;
import com.gcstorage.tvdev.net.ApiAddress;
import com.gcstorage.tvdev.net.DownloadProgressListener;
import com.gcstorage.tvdev.net.HttpClient;
import com.gcstorage.tvdev.net.RxObserver;
import com.google.gson.JsonElement;
import com.lzy.okgo.callback.FileCallback;
import com.lzy.okgo.model.Progress;
import com.lzy.okgo.model.Response;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**
 * 小程序管理类
 * created by Sanpark on 2021-07-22 15:01
 */
public class H5AppManager {
    private static H5AppManager instance;

    public static H5AppManager getInstance() {
        if (instance == null) {
            synchronized (H5AppManager.class) {
                if (instance == null) {
                    instance = new H5AppManager();
                }
            }
        }
        return instance;
    }

    private H5AppManager() {
    }

    public void downloadApp(H5AppInfo h5AppInfo, DownloadProgressListener listener) {
        String proPath = h5AppInfo.getProPath();
        String proFile = h5AppInfo.getProFile();
        String zipPath = h5AppInfo.getZipPath();
        String zipFile = h5AppInfo.getZipFile();
        FileUtils.createOrExistsDir(zipPath);
        if (FileUtils.isFileExists(zipFile)) {
            if (h5AppInfo.getMd5() == null) {
                ToastUtils.showShort(String.format("小程序%s完整性缺失,请联系管理员", h5AppInfo.getAppName()));
            } else {
                String fileMd5 = FileUtils.getFileMD5ToString(zipFile);
                if (fileMd5.equalsIgnoreCase(h5AppInfo.getMd5())) {
                    LogUtils.d("H5APP", zipPath + "文件已下载");
                    deleteRedundancy(h5AppInfo);
                    if (!FileUtils.isFileExists(proFile)) {
                        try {
                            ZipUtils.unzipFile(new File(zipFile), new File(proPath));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    ToastUtils.showShort("小程序损毁，请联系管理员");
                    FileUtils.deleteAllInDir(proPath);
                }
            }
        } else {
            HttpUtils.downloadFile(h5AppInfo.getDownloadUrl(), this, new FileCallback(zipPath, "vue.zip") {
                @Override
                public void onSuccess(Response<File> response) {
                    listener.onSuccess();
                }

                @Override
                public void onError(Response<File> response) {
                    super.onError(response);
                    listener.onError(response.code(), response.message());
                }

                @Override
                public void onFinish() {
                    super.onFinish();
                    listener.onFinish();
                }

                @Override
                public void downloadProgress(Progress progress) {
                    super.downloadProgress(progress);
                    listener.update(progress.currentSize, progress.totalSize, progress.fraction == 1);
                }
            });
            // HttpClient.get().downloadH5App(h5AppInfo.getDownloadUrl(), zipPath, listener);
        }
    }

    public void downloadApp(H5AppInfo h5AppInfo, boolean isOpen) {
        downloadApp(h5AppInfo, null, isOpen);
    }

    public void downloadApp(H5AppInfo h5AppInfo, String params, boolean isOpen) {
        downloadApp(h5AppInfo, new DownloadProgressListener() {
            @Override
            public void update(long bytesRead, long contentLength, boolean done) {
            }

            @Override
            public void onSuccess() {
                super.onSuccess();
                if (FileUtils.isFileExists(h5AppInfo.getZipFile())) {
                    deleteRedundancy(h5AppInfo);
                    if (!FileUtils.isFileExists(h5AppInfo.getProFile())) {
                        try {
                            ZipUtils.unzipFile(new File(h5AppInfo.getZipFile()), new File(h5AppInfo.getProPath()));
                            if (isOpen) {
                                if (params != null) {
                                    h5AppInfo.setParams(params);
                                }
                                JumpHelper.gotoH5Activity(BaseApplication.getInstance(), h5AppInfo.getWebUrl(), true, h5AppInfo.getAppName(), h5AppInfo);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            ToastUtils.showShort("解压小程序出现错误");
                        }
                    }

                }
            }
        });
    }

    //vue直接下载小程序最新版
    public void downloadAppByAppId(String appId) {
        HttpClient.get().get(AppConstant.getApiAddress() + ApiAddress.APP_SELECT_BY_ID, Collections.singletonMap("appId", appId), new RxObserver() {
            @Override
            public void onSuccess(JsonElement t) {
                H5AppInfo h5AppInfo = GsonUtils.covertObject(t, H5AppInfo.class).getData();
                if (h5AppInfo.getId().equals("-1")) {
                    return;
                }
                if (FileUtils.isFileExists(h5AppInfo.getZipFile())) {
                    deleteRedundancy(h5AppInfo);
                    if (!FileUtils.isFileExists(h5AppInfo.getProFile())) {
                        try {
                            ZipUtils.unzipFile(new File(h5AppInfo.getZipFile()), new File(h5AppInfo.getProPath()));
                        } catch (IOException e) {
                            e.printStackTrace();
                            ToastUtils.showShort("解压小程序出现错误");
                        }
                    }
                } else {
                    downloadApp(h5AppInfo, false);
                }
            }
        });
    }

    public void openApp(H5AppInfo h5AppInfo) {
        openApp(h5AppInfo, "");
    }

    //打开小程序，并使用url为打开链接
    public void openApp(H5AppInfo h5AppInfo, String url) {
        if (h5AppInfo.getAppId().equals("-1")) {
            ToastUtils.showShort("小程序不存在");
            return;
        }
        HashMap<String, Object> request = new HashMap<>();
        request.put("appId", h5AppInfo.getAppId());
        request.put("appName", h5AppInfo.getAppName());
        HttpClient.get().postBody(AppConstant.getApiAddress() + ApiAddress.COMMON_H5_ACTION, request, new RxObserver() {
            @Override
            public void onSuccess(JsonElement t) {

            }
        });
        String proFile = h5AppInfo.getProFile();
        String zipFile = h5AppInfo.getZipFile();
        if (FileUtils.isFileExists(proFile)) {
            if (FileUtils.isFileExists(zipFile)) {
                JumpHelper.gotoH5Activity(BaseApplication.getInstance(), TextUtils.isEmpty(url) ? h5AppInfo.getWebUrl() : url, true, h5AppInfo.getAppName(), h5AppInfo);
            } else {
                downloadApp(h5AppInfo, true);
            }
        } else {
            downloadApp(h5AppInfo, true);
        }
    }

    public void openAppByUrl(String url) {
        if (url.startsWith("http://")) {
            JumpHelper.gotoH5Activity(BaseApplication.getInstance(), url, false, "");
        } else {
            if (url.startsWith("file:///")) {
                String appId = url.split("/")[8];
                openAppByAppId(appId, url);
            } else {
                ToastUtils.showShort("未知链接,请检查配置");
            }
        }
    }

    public void openAppByAppId(String appId) {
        openAppByAppId(appId, "");
    }

    //打开小程序，并使用url为打开链接
    public void openAppByAppId(String appId, String url) {
        HttpClient.get().get(AppConstant.getApiAddress() + ApiAddress.APP_SELECT_BY_ID, Collections.singletonMap("appId", appId), new RxObserver() {
            @Override
            public void onSuccess(JsonElement t) {
                H5AppInfo h5AppInfo = GsonUtils.covertObject(t, H5AppInfo.class).getData();
                if (h5AppInfo != null) {
                    openApp(h5AppInfo, url);
                }
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                ToastUtils.showShort("获取小程序信息失败");
            }
        });
    }

    public void openAppByAppIdWithParam(String appId, String params) {
        HttpClient.get().get(AppConstant.getApiAddress() + ApiAddress.APP_SELECT_BY_ID, Collections.singletonMap("appId", appId), new RxObserver() {
            @Override
            public void onSuccess(JsonElement t) {
                H5AppInfo h5AppInfo = GsonUtils.covertObject(t, H5AppInfo.class).getData();
                if (h5AppInfo != null) {
                    openApp(h5AppInfo, getAppIdLocalUrl(appId, params));
                }
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                ToastUtils.showShort("获取小程序信息失败");
            }
        });
    }

    //删除当前版本外的所有包
    public void deleteRedundancy(H5AppInfo h5AppInfo) {
        List<File> fileList = FileUtils.listFilesInDirWithFilter(h5AppInfo.getProPath(), new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                String filePath = h5AppInfo.getProPath();
                // return !pathname.getPath().equals(filePath + "/static") && !pathname.getPath().equals(filePath + "/index.html") && !pathname.getPath().equals(filePath + "/" + h5AppInfo.getVersionNum());
                return !pathname.getPath().equals(filePath + "/" + h5AppInfo.getVersionNum());
            }
        });
        for (int i = 0; i < fileList.size(); i++) {
            FileUtils.delete(fileList.get(i).getPath());
        }
    }

    public boolean isExistApp(String appId) {
        return FileUtils.isFileExists(GlobalConstants.H5_APP_DOWNLOAD_DIR + "/" + appId + "/index.html");
    }

    public static String getAppIdLocalUrl(String appId) {
        return getAppIdLocalUrl(appId, "");
    }

    public static String getAppIdLocalUrl(String appId, String params) {
        return "file:///mnt/sdcard/gcstorage/app/" + SpUtils.getString(AppConstant.tenantId) + "/" + appId + "/index.html" + params;
    }

    public static String getFilePreview(String fileId) {
        return "file:///mnt/sdcard/gcstorage/app/" + SpUtils.getString(AppConstant.tenantId) + "/" +
                AppConstant.APP_ID_PREVIEW + "/index.html?active=/index&fileId=" + fileId;
    }
}
